package com.cangxuan.backend.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.cangxuan.backend.bean.Result;
import com.cangxuan.backend.dao.*;
import com.cangxuan.backend.entity.*;
import com.cangxuan.backend.exception.ServiceException;
import com.cangxuan.backend.service.IRegistrationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Author: 陈青石
 * 挂单接口实现
 */
@Service
@Slf4j
public class RegistrationServiceImpl extends BaseServiceImpl implements IRegistrationService {

    IRegistrationDao registrationDao;

    IUserGoodsDao userGoodsDao;

    IBillDao billDao;

    IOrderFormDao orderFormDao;
    IGoodsDao goodsDao;
    IUserDao userDao;

    DataSourceTransactionManager transactionManager;

    RestTemplate restTemplate;

    @Autowired
    public void setRestTemplate(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }
    @Autowired
    public void setUserDao(IUserDao userDao) {
        this.userDao = userDao;
    }

    @Autowired
    public void setGoodsDao(IGoodsDao goodsDao) {
        this.goodsDao = goodsDao;
    }

    @Autowired
    public void setOrderFormDao(IOrderFormDao orderFormDao) {
        this.orderFormDao = orderFormDao;
    }

    @Autowired
    public void setBillDao(IBillDao billDao) {
        this.billDao = billDao;
    }

    @Autowired
    public void setTransactionManager(DataSourceTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    @Autowired
    public void setRegistrationDao(IRegistrationDao registrationDao) {
        this.registrationDao = registrationDao;
    }

    @Autowired
    public void setUserGoodsDao(IUserGoodsDao userGoodsDao) {
        this.userGoodsDao = userGoodsDao;
    }

    @Override
    public List<Registration> selectRegistrationsByGoodsId(int goodsId) {
        return registrationDao.selectRegistrationsByGoodsId(goodsId);
    }


    @Override
    public Map<String, Object> changeCount(List<Registration> registrationList) {

        if (registrationList.size() > 10) {
            throw new ServiceException(415, "对不起你所选择的挂单数量大于10");
        }
        if (registrationList.size() == 0) {
            throw new ServiceException(415, "请选择需要购买的挂单");
        }

        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
        List<OrderForm> successBuy = new ArrayList<>();

        StringBuffer stringBuffer = new StringBuffer("对不起已正在被购买的挂单编号有：");

        boolean success = true;

        int userId = getCurrentUser().getId();

        TransactionStatus transaction1 = transactionManager.getTransaction(definition);
        int row = orderFormDao.selectUserHavaOrderForm(userId);
        if (row != 0) {
            transactionManager.rollback(transaction1);
            throw new ServiceException(415, "对不起你还有未支付的订单，请先完成订单");
        } else {
            transactionManager.commit(transaction1);
        }

        for (Registration registration : registrationList) {
            TransactionStatus transaction = transactionManager.getTransaction(definition);
            //查询buyer_id,是否为0 上锁
            Registration registration1 = registrationDao.selectById(registration.getId());
            if (registration1.getBuyerId() == 0) {
                int res = 0;
                //修改registration.id的count-1,把buyer_id改为userId
                res += registrationDao.updateCount(registration1.getId(), userId);
                //创建orderform
                //获取手续费率
                Goods goods = goodsDao.selectById(registration1.getGoodsId());
                float feeRate = goods.getFeeRate();
                Float amount = Float.valueOf(registration1.getPrice());
                Float free = Float.valueOf(amount * feeRate);
                Float act = amount - free;
                OrderForm orderForm = new OrderForm(0, userId, registration1.getUserId(), registration1.getGoodsId(), amount, 1, amount, free, act, null, null, 1, registration.getId(), null, null, null);
                orderFormDao.createOrderForm(orderForm);
                int orderFormId = orderForm.getId();
                if (res == 1) {
                    OrderForm returnOderForm = orderFormDao.selectById(orderFormId);
                    successBuy.add(returnOderForm);
                    transactionManager.commit(transaction);
                } else {
                    success = false;
                    stringBuffer.append(registration.getId() + "、");
                    transactionManager.rollback(transaction);
                }
            } else {
                success = false;
                stringBuffer.append(registration.getId() + "、");
                transactionManager.rollback(transaction);
            }

        }

        if (successBuy.size() == 0) {
            throw new ServiceException(415, "对不起你选购的订单都已正在被其他用户所购买，请稍后购买");
        }

        Map<String, Object> res = new HashMap<>();

        if (success == false) {
            res.put("message", stringBuffer.toString().substring(0, stringBuffer.length() - 1));
            res.put("list", successBuy);
        } else {
            res.put("message", "创建订单成功");
            res.put("list", successBuy);
        }


        return res;

    }

    @Override
    public void successPay(List<OrderForm> orderFormList) {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        StringBuffer stringBuffer = new StringBuffer("对不起，支付失败的订单编号有：");

        boolean success = true;

        int userId = getCurrentUser().getId();


        for (OrderForm orderForm : orderFormList) {
            TransactionStatus transaction = transactionManager.getTransaction(definition);
            try {

                //通过orderform.id获取Orderfrom的registrationId
                //使用registrationId获取BuyerId
                Registration registration = registrationDao.selectBuyerIdById(orderForm.getId());
                if (registration.getBuyerId() != 0) {
                    //查询orderform
                    OrderForm orderForm1 = orderFormDao.selectByIdForUpdate(orderForm.getId());
                    if (orderForm1 == null) {
                        success = false;
                        stringBuffer.append(orderForm.getId() + "、");
                        transactionManager.rollback(transaction);
                        continue;
                    }
                    //判断是否超时
                    int isOver = orderFormDao.selectIsOverTime(orderForm.getId());
                    if (isOver > 0) {
                        success = false;
                        stringBuffer.append(orderForm.getId() + "、");
                        orderFormDao.updateForCancel(orderForm.getId());
                        registrationDao.updateForCancelPay(registration.getId());
                        transactionManager.commit(transaction);
                        continue;
                    }

                    int res = 0;
                    //修改registration.buyerId，上锁
                    res += registrationDao.unlockBuyerId(registration.getId());
                    //修改orderform.state_id
                    res += orderFormDao.updateForSuccessPay(orderForm1.getId());
                    //创建user_goods
                    UserGoods userGoods = new UserGoods(userId, orderForm1.getGoodsId(), registration.getId(), 1);
                    res += userGoodsDao.insertForGoods(userGoods);
                    //创建user_amount_record,双方
                    res += billDao.insertRecord(new UserAmountRecord(userId, 0, orderForm1.getPrice(), "支出：" + orderForm1.getPrice() + "元，购买" + registration.getUserId() + "的" + registration.getGoodsId() + "号藏品", orderForm1.getId()));
                    res += billDao.insertRecord(new UserAmountRecord(registration.getUserId(), 1, orderForm1.getPrice(), "收入：" + orderForm1.getActualReceipt() + "元，用户" + userId + "成功购买了你的" + registration.getGoodsId() + "号藏品", orderForm1.getId()));
                    if (res == 5) {
                        //获取卖家registrationId
                        User user = userDao.selectById(orderForm1.getSellerId());
                        new Thread(()->{
                            JSONObject body = new JSONObject();
                            body.put("registrationId", user.getRegistrationId());
                            body.put("message", "你的编号为："+orderForm1.getRegistrationId()+"的挂单被购买，请到到详情页面进行查看");
                            Result result = restTemplate.postForObject("http://CangXuanPushService/api/pushMessageToUser", body, Result.class);
                            if (result.getMessage().equals("OK")) {
                                log.info("发送通知成功","orderformId:"+orderForm.getId());
                            } else {
                                log.info("发送通知失败","orderformId:"+orderForm.getId());
                            }
                        }).start();
                        transactionManager.commit(transaction);
                    } else {
                        success = false;
                        stringBuffer.append(orderForm.getId() + "、");
                        transactionManager.rollback(transaction);
                    }
                } else {
                    success = false;
                    stringBuffer.append(orderForm.getId() + "、");
                    transactionManager.rollback(transaction);
                }
            } catch (Exception e) {
                success = false;
                stringBuffer.append(orderForm.getId() + "、");
                transactionManager.rollback(transaction);
            }


        }


        if (success == false) {
            throw new ServiceException(415, stringBuffer.toString().substring(0, stringBuffer.length() - 1));
        }

    }

    @Override
    public int cancelPay(List<OrderForm> orderFormList) {
        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
        OrderForm orderForm = orderFormList.get(0);


        TransactionStatus transaction = transactionManager.getTransaction(definition);

        Registration registration = registrationDao.selectBuyerIdById(orderForm.getId());
        try {
            if (registration.getBuyerId() != 0) {
                transactionManager.commit(transaction);
                TransactionStatus transaction1 = transactionManager.getTransaction(definition);
                int res = 0;
                //Registration.buyer_id改为0，count+1上锁，
                res += registrationDao.updateForCancelPay(registration.getId());
                //orderform状态改为3
                res += orderFormDao.updateForCancel(orderForm.getId());
                if (res == 2) {
                    transactionManager.commit(transaction1);
                    return res;
                } else {
                    throw new ServiceException(415, "取消订单失败");
                }
            } else {
                throw new ServiceException(415, "取消订单失败");
            }
        } catch (Exception e) {
            transactionManager.rollback(transaction);
            throw new ServiceException(415, "取消订单失败");
        }
    }


    @Override
    public void overTime(List<OrderForm> orderFormList) {

        DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
        definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        definition.setIsolationLevel(TransactionDefinition.ISOLATION_SERIALIZABLE);
        OrderForm orderForm = orderFormList.get(0);
        TransactionStatus transaction = transactionManager.getTransaction(definition);
        String message = "超时判断失败";
        //上锁获取
        try {
            if (orderFormDao.selectIsOverTime(orderForm.getId()) != 0) {
                Registration registration = registrationDao.selectBuyerIdById(orderForm.getId());
                if (registration.getBuyerId() != 0) {
                    int res = 0;
                    //Registration.buyer_id改为0，count+1上锁，
                    res += registrationDao.updateForCancelPay(registration.getId());
                    //orderform状态改为3
                    res += orderFormDao.updateForCancel(orderForm.getId());
                    if (res == 2) {
                        message = "订单超时";
                        transactionManager.commit(transaction);
                        throw new ServiceException(415, "订单超时");
                    } else {
                        message = "取消订单失败";
                        transactionManager.rollback(transaction);
                        throw new ServiceException(415, "取消订单失败");
                    }
                } else {
                    message = "取消订单失败";
                    transactionManager.rollback(transaction);
                    throw new ServiceException(415, "取消订单失败");
                }
            } else {
                transactionManager.commit(transaction);
            }
        } catch (Exception e) {
            throw new ServiceException(415, message);
        }


    }
}
